home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlib25 / _fxunsd.cpp < prev    next >
C/C++ Source or Header  |  1992-09-29  |  3KB  |  151 lines

  1. |
  2. | double float to unsigned long conversion routine
  3. | does not really return unsigned long: max result is 0x7fffffff
  4. | mjr
  5.     .text
  6.     .even
  7.     .globl    __fixunsdfsi, ___fixunsdfsi
  8.  
  9. #ifdef ERROR_CHECK
  10. #include "errbase.h"
  11. _Overflow:
  12.     .ascii "OVERFLOW\0"
  13. _Negative:
  14.     .ascii "NEGATIVE NUMBER\0"
  15. _Error_String:
  16.     .ascii "_fixunsdfsi: %s error\n\0"
  17. .even
  18. #endif ERROR_CHECK
  19.  
  20. __fixunsdfsi:
  21. ___fixunsdfsi:
  22.  
  23. #ifdef ERROR_CHECK
  24.     tstl    a7@(4)            | negative?
  25.     beq    Continue
  26.     moveq    #ERANGE,d0
  27.     Emove    d0,Errno
  28.     pea    pc@(_Negative)
  29.     bra    error_exit
  30. Continue:
  31. #endif /* ERROR_CHECK */
  32. #ifdef __M68881__
  33.  
  34.     fintrzd a7@(4),fp0        | convert
  35.     fmovel    fp0,d0
  36.  
  37. #endif __M68881__
  38.  
  39. #ifdef    sfp004
  40. | double float to unsigned long conversion routine
  41. | does not really return unsigned long: max result is 0x7fffffff
  42. | mjr
  43.  
  44. comm =     -6
  45. resp =    -16
  46. zahl =      0
  47.  
  48.     lea    0xfffffa50:w,a0
  49.     movew    #0x5403,a0@(comm)    | fintrz to fp0
  50.     cmpiw    #0x8900,a0@(resp)    | check
  51.     movel    a7@(4),a0@
  52.     movel    a7@(8),a0@
  53.     movew    #0x6000,a0@(comm)    | result to d0
  54.     .long    0x0c688900, 0xfff067f8
  55.     movel    a0@,d0
  56. #endif    sfp004
  57.  
  58. # if !defined (sfp004) && !defined (__M68881__)
  59.  
  60. | double float to unsigned long conversion routine
  61. |
  62. | written by Kai-Uwe Bloem (I5110401@dbstu1.bitnet).
  63. | Based on a 80x86 floating point packet from comp.os.minix, written by P.Housel
  64. |
  65. |
  66. | Revision 1.3, kub 01-90 :
  67. | added support for denormalized numbers
  68. |
  69. | Revision 1.2, kub 01-90 :
  70. | replace far shifts by swaps to gain speed
  71. |
  72. | Revision 1.1, kub 12-89 :
  73. | Ported over to 68k assembler
  74. |
  75. | Revision 1.0:
  76. | original 8088 code from P.S.Housel
  77.  
  78. BIAS8    =    0x3FF-1
  79.  
  80.     lea    sp@(4),a0    | pointer to parameters
  81.     moveml    d4/d5,sp@-    | save registers
  82.     moveml    a0@,d4-d5    | get the number
  83.     movew    a0@,d0        | extract exp
  84.     lsrw    #4,d0
  85.     andw    #0x07ff,d0    | kill sign bit
  86.  
  87.     andl    #0x0fffff,d4    | remove exponent from mantissa
  88.     orl    #0x100000,d4    | restore implied leading "1"
  89.  
  90.     cmpw    #BIAS8,d0    | check exponent
  91.     blt    zero        | strictly factional, no integer part ?
  92.     cmpw    #BIAS8+32,d0    | is it too big to fit in a 32-bit integer ?
  93.     bgt    toobig
  94.  
  95.     subw    #BIAS8+21,d0    | adjust exponent
  96.     bgt    2f        | shift up
  97.     beq    3f        | no shift
  98.  
  99.     cmpw    #-8,d0        | replace far shifts by swap
  100.     bgt    1f
  101.     movew    d4,d5        | shift fast, 16 bits
  102.     swap    d5
  103.     clrw    d4
  104.     swap    d4
  105.     addw    #16,d0        | account for swap
  106.     bgt    2f
  107.     beq    3f
  108.  
  109. 1:    lsrl    #1,d4        | shift down to align radix point;
  110.     addw    #1,d0        | extra bits fall off the end (no rounding)
  111.     blt    1b        | shifted all the way down yet ?
  112.     bra    3f
  113.  
  114. 2:    addl    d5,d5        | shift up to align radix point
  115.     addxl    d4,d4
  116.     subw    #1,d0
  117.     bgt    2b
  118. 3:
  119.     movel    d4,d0        | put integer into result register
  120. 7:
  121.     moveml    sp@+,d4/d5
  122.     rts
  123.  
  124. zero:
  125.     clrl    d0        | make the whole thing zero
  126.     bra    7b
  127.  
  128. toobig:
  129.     moveml    sp@+,d4/d5
  130.     movel    #0x7fffffff,d0    | ugh. Should cause a trap here.
  131. #endif
  132.  
  133. #ifdef    ERROR_CHECK
  134.     cmpil    #0x7fffffff,d0    | >= long_max
  135.     bge    error_plus    |
  136.     rts
  137. error_plus:
  138.     moveml    d0-d1,a7@-
  139.     moveq    #ERANGE,d0
  140.     Emove    d0,Errno
  141.     pea    pc@(_Overflow)    | for printf
  142. error_exit:
  143.     pea    pc@(_Error_String)    |
  144.     pea    Stderr
  145.     jbsr    _fprintf    |
  146.     addl    #12,a7        |
  147.     moveml    a7@+,d0-d1
  148. #endif    ERROR_CHECK
  149.     rts
  150.  
  151.